/* api */
import { getRobot, getRobotOutsideModulesApp, updateRobotSetting } from '@src/api/AIApi';
/* model */
import {
  DefaultRobotItem,
  SettingGPTChannelEnum,
  SettingGPTRobotSettingTypeEnum
} from '@src/modules/setting/gpt/model'
import MsgModel from '@model/MsgModel';
/* api */
import { DeleteGPTRobotAppServiceModel, GetAddGPTRobotAppModel, GetGPTRobotModel, UpdateOpenDDAssistantModel, UpdateRobotSettingModel } from '@model/param/in/AI';
/* hooks */
import { useLoading } from '@hooks/useLoading';
import { useFetchSettingGPTRobotAppAdd, useFetchSettingGPTRobotAppDelete, useFetchSettingGPTRobotAppListWithSetting, useFetchSettingGPTRobotCheckRepeatSettingReleaseChannel, useFetchSettingGPTRobotUpdateOpenDDAssistant, useFetchSettingGPTRobotUpdateSettingModelName, useFetchSettingGPTRobotUpdateSettingReleaseChannel } from '@gpt/hooks/robot';
/* vue */
import { computed, Ref, ref } from 'vue'
/* utils */
import qs from 'qs';
import { confirm } from '@src/util/platform';
import { isFalsy } from '@src/util/type';
import { message } from '@src/util/message';
import { 
  transformRobotServerItemToComponentItem, 
  getRobotOutsideModulesByModuleGroups, 
  transformRobotOutsideAppToOutsideModule
} from '@src/modules/setting/gpt/utils';
import { openTabGptRobotList } from '@src/util/business/openTab';
/* type */
import { AIChatRobotItemType } from '@src/component/business/BizChatPanel/chat/types';
import { AIChatRobotItemComponentType } from '@src/modules/setting/gpt/types';
import { 
  SettingGPTRobotOutsideModuleAppGroupType, 
  SettingGPTRobotOutsideModuleAppType 
} from "src/modules/setting/gpt/types"
import { closeCurrentTab } from '@src/platform';

function useSettingGPTRobotEdit() {
  
  const {
    robotId,
    isEdit
  } = useSettingGPTRobotEditStatus()
  
  const {
    loading: fetchUpdateGptRobotSettingModelNameLoading,
    fetchUpdateGptRobotSettingModelName,
    isSuccess: fetchUpdateGptRobotSettingModelNameSuccess
  } = useFetchSettingGPTRobotUpdateSettingModelName()
  
  const {
    loading: fetchUpdateGptRobotSettingReleaseChannelLoading,
    fetchUpdateGptRobotSettingReleaseChannel,
    isSuccess: fetchUpdateGptRobotSettingReleaseChannelSuccess
  } = useFetchSettingGPTRobotUpdateSettingReleaseChannel()
  
  const {
    loading: fetchSettingGPTRobotCheckRepeatSettingReleaseChannelLoading,
    fetchCheckRepeatSettingReleaseChannel,
    isSuccess: fetchCheckRepeatSettingReleaseChannelSuccess,
    isRepeat: isRepeatSettingReleaseChannel
  } = useFetchSettingGPTRobotCheckRepeatSettingReleaseChannel()
  
  const {
    loading: fetchGptRobotUpdateOpenDDAssistantLoading,
    isSuccess: fetchGptRobotUpdateOpenDDAssistantSuccess,
    fetchUpdateOpenDDAssistant
  } = useFetchSettingGPTRobotUpdateOpenDDAssistant()
  
  const {
    loading: fetchGptRobotAppAddLoading,
    fetchGptRobotAppAdd,
    isSuccess: fetchGptRobotAppAddSuccess
  } = useFetchSettingGPTRobotAppAdd()
  
  const {
    loading: fetchGptRobotAppDeleteLoading,
    fetchGptRobotAppDelete,
    isSuccess: fetchGptRobotAppDeleteSuccess
  } = useFetchSettingGPTRobotAppDelete()
  
  const {
    loading: fetchGptRobotAppListLoading,
    fetchGptRobotAppListWithSetting: fetchGptRobotAppList,
    gptRobotAppListWithSetting: gptRobotAppList,
    chatRobotAppList
  } = useFetchSettingGPTRobotAppListWithSetting()
  
  const {
    loading: fetchGptRobotLoading,
    fetchGptRobot,
    gptRobot
  } = useFetchSettingGPTRobot()
  
  const {
    fetchRobotOutsideModuleList,
    outsideModuleList
  } = useFetchSettingGPTRobotOutsideModuleList()
  
  const {
    loading: fetchUpdateGptRobotSettingLoading,
    isSuccess: fetchUpdateGptRobotSettingSuccess,
    fetchUpdateGptRobotSetting
  } = useFetchSettingGPTRobotUpdateSetting()
  
  const loading = computed(() => {
    return (
      fetchGptRobotLoading.value 
      || fetchUpdateGptRobotSettingLoading.value
      || fetchUpdateGptRobotSettingModelNameLoading.value 
      || fetchGptRobotAppDeleteLoading.value
      || fetchGptRobotAppAddLoading.value
      || fetchUpdateGptRobotSettingReleaseChannelLoading.value
      || fetchSettingGPTRobotCheckRepeatSettingReleaseChannelLoading.value
      || fetchGptRobotUpdateOpenDDAssistantLoading.value
    )
  })
  
  const allOutsideModules = computed(() => {
    return transformRobotOutsideAppToOutsideModule(outsideModuleList.value)
  })
  
  const onfetchGptRobotAppListHandler = (_robotId?: string) => {
    const params = {
      robotId: _robotId || robotId.value
    }
    return fetchGptRobotAppList(params)
  }
  
  const initialize = () => {
    
    fetchGptRobot({
      id: robotId.value
    })
    
    fetchGptRobotAppList({
      robotId: robotId.value
    })
    
  }
  
  const onUpdateRobotSettingHandler = (params: UpdateRobotSettingModel) => {
    return fetchUpdateGptRobotSetting(params).then(() => {
      
      if (fetchUpdateGptRobotSettingSuccess.value) {
        
        openTabGptRobotList()
        
        setTimeout(() => {
          closeCurrentTab()
        }, 300)
        
      }
      
      return fetchUpdateGptRobotSettingSuccess.value
      
    })
  }
  
  const onUpdateRobotSettingModelNameHandler = (modelName: string) => {
    
    const params = {
      id: robotId.value,
      modelName: modelName
    }
    
    return fetchUpdateGptRobotSettingModelName(params).then(() => {
      
      if (fetchUpdateGptRobotSettingModelNameSuccess.value) {
        initialize()
      }
      
      return fetchUpdateGptRobotSettingModelNameSuccess.value
    })
    
  }
  
  const onUpdateRobotSettingReleaseChannelHandler = (releaseChannel: number) => {
    
    const params = {
      id: robotId.value,
      releaseChannel: releaseChannel
    }
    
    return fetchUpdateGptRobotSettingReleaseChannel(params).then(() => {
      
      if (fetchUpdateGptRobotSettingReleaseChannelSuccess.value) {
        initialize()
      }
      
      return fetchUpdateGptRobotSettingReleaseChannelSuccess.value
    })
    
  }
  
  const onUpdateRobotSettingReleaseChannelCheckRepeatHandler = async (releaseChannel: number) => {
    
    const params = {
      id: robotId.value,
      releaseChannel: releaseChannel
    }
    
    // 需要检查重复的发布渠道列表
    const needCheckRepeatChannelList = [
      SettingGPTChannelEnum.IM,
      SettingGPTChannelEnum.WeChat,
      SettingGPTChannelEnum.Portal
    ]
    // 是否需要检查重复
    const isNeedCheckRepeat = needCheckRepeatChannelList.includes(releaseChannel)
    // 如果不需要检查重复, 则更新发布渠道
    if (isFalsy(isNeedCheckRepeat)) {
      onUpdateRobotSettingReleaseChannelHandler(releaseChannel)
      return
    }
    
    const isRepeat = await fetchCheckRepeatSettingReleaseChannel(params)
    // 如果不重复, 则更新发布渠道
    if (isFalsy(isRepeat)) {
      onUpdateRobotSettingReleaseChannelHandler(releaseChannel)
      return
    }
    
    const confirmed = await confirm('目前已有其他机器人设置了该发布渠道，是否继续绑定，继续绑定将会清除其他机器人的发布渠道设置!')
    if (isFalsy(confirmed)) {
      return
    }
     
    onUpdateRobotSettingReleaseChannelHandler(releaseChannel)
  }
  
  const onUpdateOpenDDAssistantHandler = async (openDDAssistant: boolean) => {
    
    const params: UpdateOpenDDAssistantModel = {
      id: robotId.value,
      openDDAssistant
    }
    
    return fetchUpdateOpenDDAssistant(params).then(result => {
      
      if (fetchGptRobotUpdateOpenDDAssistantSuccess.value) {
        initialize()
      }
      
      return result
      
    })
    
  }
  
  const onDelRobotAppServiceHandler = async (params: DeleteGPTRobotAppServiceModel) => {
    
    const confirmed = await confirm('确认删除？')
    if (isFalsy(confirmed)) {
      return
    }
    
    return fetchGptRobotAppDelete(params).then(() => {
      
      if (fetchGptRobotAppDeleteSuccess.value) {
        initialize()
      }
      
      return fetchGptRobotAppDeleteSuccess.value
    })
  }
  
  const onAddRobotAppServiceHandler = (params: GetAddGPTRobotAppModel) => {
    return fetchGptRobotAppAdd(params).then(() => {
      
      if (fetchGptRobotAppAddSuccess.value) {
        initialize()
      }
      
      return fetchGptRobotAppAddSuccess.value
    })
  }
  
  return {
    robotId,
    initialize,
    loading,
    allOutsideModules,
    gptRobot,
    gptRobotAppList,
    fetchGptRobotAppAdd,
    onUpdateRobotSettingHandler,
    onUpdateRobotSettingModelNameHandler,
    onDelRobotAppServiceHandler,
    onfetchGptRobotAppListHandler,
    onAddRobotAppServiceHandler,
    onUpdateOpenDDAssistantHandler,
    onUpdateRobotSettingReleaseChannelHandler,
    onUpdateRobotSettingReleaseChannelCheckRepeatHandler
  }
}

/**
 * @description 获取 小宝 GPT 机器人
 */
function useFetchSettingGPTRobot() {
  
  const { loading, setLoading, clearLoading } = useLoading()
  
  let gptRobot: Ref<AIChatRobotItemComponentType> = ref(DefaultRobotItem) as Ref<AIChatRobotItemComponentType>
  
  const fetchGptRobot = (params: GetGPTRobotModel) => {
    
    setLoading()
    
    return (
      getRobot(params).then(result => {
        
        if (MsgModel.isSuccess(result)) {
          
          const data = MsgModel.getData<AIChatRobotItemType>(result, {} as AIChatRobotItemType)
          
          gptRobot.value = transformRobotServerItemToComponentItem(data)
          
        } else {
          message.error(MsgModel.getMessage(result))
        }
        
      }).finally(() => {
        clearLoading()
      })
    )
  }
  
  return {
    loading,
    fetchGptRobot,
    gptRobot
  }
}


function useSettingGPTRobotEditStatus() {
  
  const query = computed(() => {
    return qs.parse(window.location.search.substr(1));
  })
  
  const robotId = computed(() => {
    return (query.value.id as string) || '';
  });
  
  const isEdit = computed(() => {
    return Boolean(robotId.value);
  })
  
  const isCreate = computed(() => {
    return isFalsy(isEdit.value);
  })
  
  return {
    robotId,
    isEdit
  }
}

/** 
 * @description 机器人模型设置 选项卡
*/
function useSettingGPTRobotEditTab() {
  
  const active: Ref<SettingGPTRobotSettingTypeEnum> = ref(SettingGPTRobotSettingTypeEnum.PrivateModel)
  
  const setActive = (type: SettingGPTRobotSettingTypeEnum) => {
    active.value = type
  }
  
  const isActive = (type: SettingGPTRobotSettingTypeEnum) => {
    return active.value === type
  }
  
  const isPrivateModelActive = computed(() => {
    return isActive(SettingGPTRobotSettingTypeEnum.PrivateModel)
  })
  
  const isPublicModelActive = computed(() => {
    return isActive(SettingGPTRobotSettingTypeEnum.PublicModel)
  })
  
  const resetActive = () => {
    setActive(SettingGPTRobotSettingTypeEnum.PrivateModel)
  }
  
  return {
    active,
    setActive,
    resetActive,
    isPrivateModelActive,
    isPublicModelActive,
  }
}

/**
 * @description 获取 小宝 GPT 机器人 外部模块列表
 */
function useFetchSettingGPTRobotOutsideModuleList() {
  
  const { loading, setLoading, clearLoading } = useLoading()
  
  const outsideModuleList: Ref<SettingGPTRobotOutsideModuleAppType[]> = ref([])
  
  const fetchRobotOutsideModuleList = () => {
    
    setLoading()
    
    return (
      getRobotOutsideModulesApp().then(result => {
        
        if (MsgModel.isSuccess(result)) {
          
          const data = MsgModel.getData<SettingGPTRobotOutsideModuleAppGroupType[]>(result, [] as SettingGPTRobotOutsideModuleAppGroupType[])
          
          outsideModuleList.value = getRobotOutsideModulesByModuleGroups(data)
          
        } else {
          message.error(MsgModel.getMessage(result))
        }
        
      }).finally(() => {
        clearLoading()
      })
    )
  }
  
  return {
    loading,
    fetchRobotOutsideModuleList,
    outsideModuleList
  }
}

/**
 * @description 获取 小宝 GPT 机器人
 */
function useFetchSettingGPTRobotUpdateSetting() {
  
  const { loading, setLoading, clearLoading } = useLoading()
  
  const isSuccess: Ref<boolean> = ref(false)
  
  const fetchUpdateGptRobotSetting = (params: UpdateRobotSettingModel) => {
    
    setLoading()
    
    return (
      updateRobotSetting(params).then(result => {
        
        isSuccess.value = MsgModel.isSuccess(result)
        
        if (isSuccess.value) {
          // 
        } else {
          message.error(MsgModel.getMessage(result))
        }
        
      }).finally(() => {
        clearLoading()
      })
    )
  }
  
  return {
    loading,
    isSuccess,
    fetchUpdateGptRobotSetting
  }
}


export {
  useSettingGPTRobotEdit,
  useSettingGPTRobotEditTab,
  useFetchSettingGPTRobotOutsideModuleList,
  useFetchSettingGPTRobotUpdateSetting,
}
